﻿using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;

namespace Simulation.Framework.Editor
{
    public enum EItemType
    {
        gameObject,
        component
    }

    public class PanelPrefabTreeViewItem : TreeViewItem
    {
        public EItemType eItemType = EItemType.gameObject;
        public bool state;
        public string strValue;
        public Component component;
        public PanelPrefabTreeViewItem(int id, int depth, string displayName) : base(id, depth, displayName)
        {
        }
    }

    public class PanelPrefabTreeView : TreeView
    {
        private List<Transform> panelRoots;
        private PanelCodeData selectedPanel;
        private PanelCodeResolver panelCodeResolver;

        public PanelPrefabTreeView(TreeViewState state, MultiColumnHeader multiColumnHeader) : base(state, multiColumnHeader)
        {
            rowHeight = 20;
            showBorder = true;
            Reload();
        }

        // 创建根节点
        protected override TreeViewItem BuildRoot()
        {
            return new TreeViewItem { id = 0, depth = -1 };
        }

        // 创建每行元素数据
        protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
        {
            if (panelRoots == null)
                return base.BuildRows(root);

            var rows = GetRows() ?? new List<TreeViewItem>();
            rows.Clear();

            for (int i = 0; i < panelRoots.Count; i++)
            {
                Transform panelRoot = panelRoots[i];
                TreeViewItem item = CreateTreeViewItemForGameObject(panelRoot.gameObject);
                root.AddChild(item);
                rows.Add(item);

                // 如果展开节点
                if (IsExpanded(item.id))
                {
                    AddChildrenRecursive(panelRoot.gameObject, item, rows);
                }
                else
                {
                    // 创建子节点列表
                    item.children = CreateChildListForCollapsedParent();
                }
            }

            // 为每一个 item 设置设置深度值
            SetupDepthsFromParentsAndChildren(root);
            return rows;
        }

        // 渲染每行元素
        protected override void RowGUI(RowGUIArgs args)
        {
            var item = (PanelPrefabTreeViewItem)args.item;
            for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
            {
                CellGUI(args.GetCellRect(i), item, args.GetColumn(i), ref args);
            }
        }

        // 双击元素选中节点
        protected override void DoubleClickedItem(int id)
        {
            base.DoubleClickedItem(id);
            PanelPrefabTreeViewItem item = FindItem(id, rootItem) as PanelPrefabTreeViewItem;
            Selection.activeObject = item.component;
            EditorGUIUtility.PingObject(item.component);
        }

        private void AddChildrenRecursive(GameObject go, TreeViewItem item, IList<TreeViewItem> rows)
        {
            item.children = new List<TreeViewItem>();

            if (!panelRoots.Contains(go.transform))
            {
                // 添加节点组件
                Component[] components = go.GetComponents<Component>();
                for (int j = 0; j < components.Length; j++)
                {
                    var component = components[j];
                    var componentItem = CreateTreeViewItemForComponent(component);
                    item.AddChild(componentItem);
                    rows.Add(componentItem);
                }
            }

            // 添加子节点
            int childCount = go.transform.childCount;
            for (int i = 0; i < childCount; ++i)
            {
                var childTransform = go.transform.GetChild(i);
                var childItem = CreateTreeViewItemForGameObject(childTransform.gameObject);

                item.AddChild(childItem);
                rows.Add(childItem);

                if (IsExpanded(childItem.id))
                {
                    AddChildrenRecursive(childTransform.gameObject, childItem, rows);
                }
                else
                {
                    childItem.children = CreateChildListForCollapsedParent();
                }
            }
        }

        private PanelPrefabTreeViewItem CreateTreeViewItemForGameObject(GameObject gameObject)
        {
            string displayName = gameObject.name;
            PanelPrefabTreeViewItem treeViewItem = new PanelPrefabTreeViewItem(gameObject.GetInstanceID(), -1, displayName);
            treeViewItem.icon = FindIcon("GameObject Icon") as Texture2D;
            treeViewItem.eItemType = EItemType.gameObject;
            treeViewItem.component = gameObject.transform;
            return treeViewItem;
        }

        private PanelPrefabTreeViewItem CreateTreeViewItemForComponent(Component component)
        {
            string displayName = component.GetType().Name;
            PanelPrefabTreeViewItem treeViewItem = new PanelPrefabTreeViewItem(component.GetInstanceID(), -1, displayName);
            treeViewItem.icon = FindIcon(displayName + " Icon") as Texture2D;
            treeViewItem.eItemType = EItemType.component;
            treeViewItem.component = component;
            treeViewItem.state = GetState(treeViewItem.component);
            return treeViewItem;
        }

        private void CellGUI(Rect cellRect, PanelPrefabTreeViewItem item, int column, ref RowGUIArgs args)
        {
            CenterRectUsingSingleLineHeight(ref cellRect);
            // 节点
            if (column == 0)
            {
                base.RowGUI(args);
            }
            // 状态
            else if (column == 1)
            {
                if (item.eItemType == EItemType.gameObject)
                    return;
                // 剔除非 UI 控件
                if (!PanelCodeResolver.IsBaseTypeUIControl(item.component.GetType()))
                    return;
                cellRect.xMin += cellRect.width * 0.5f;
                Rect toggleRect = cellRect;
                toggleRect.width = 18;
                bool value = item.state;
                item.state = EditorGUI.Toggle(toggleRect, item.state);
                // 插入
                if (value != item.state && item.state)
                    InsertField(item.component);
                else if (value != item.state && !item.state)
                    DeleteField(item.component);
            }
            // 注释
            else if (column == 2)
            {
                if (item.eItemType == EItemType.gameObject)
                    return;
                Rect textRect = cellRect;
                textRect.width = cellRect.width;
                item.strValue = EditorGUI.TextField(textRect, item.strValue);
            }
        }

        public void SetRoot(List<Transform> roots, PanelCodeData selectedPanel)
        {
            panelRoots = roots;
            this.selectedPanel = selectedPanel;
            this.panelCodeResolver = new PanelCodeResolver(selectedPanel);
            panelCodeResolver.Parse();
            Reload();
        }

        /// <summary>
        /// 创建 title
        /// </summary>
        public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState(float treeViewWidth)
        {
            MultiColumnHeaderState.Column[] columns = new MultiColumnHeaderState.Column[]
            {
                new MultiColumnHeaderState.Column
                {
                    headerContent = new GUIContent("节点", "页面中的所有节点"),
                    headerTextAlignment = TextAlignment.Center,
                    sortedAscending = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width = 200,
                    minWidth = 60,
                    autoResize = false,
                    allowToggleVisibility = false
                },
                new MultiColumnHeaderState.Column
                {
                    headerContent = new GUIContent("状态", "脚本中添加该类型的字段"),
                    headerTextAlignment = TextAlignment.Center,
                    sortedAscending = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width = 200,
                    minWidth = 60,
                    autoResize = false,
                    allowToggleVisibility = false
                },
                new MultiColumnHeaderState.Column
                {
                    headerContent = new GUIContent("注释", "对该属性的注释"),
                    headerTextAlignment = TextAlignment.Center,
                    sortedAscending = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width = 200,
                    minWidth = 60,
                    autoResize = false,
                    allowToggleVisibility = false
                }
            };

            return new MultiColumnHeaderState(columns);
        }

        private Texture FindIcon(string iconName)
        {
            return EditorGUIUtility.IconContent(iconName).image;
        }

        public bool GetState(Component component)
        {
            return panelCodeResolver.ContainsComponent(component);
        }

        public void InsertField(Component component)
        {
            panelCodeResolver.InsertField(component);
        }

        public void DeleteField(Component component)
        {
            panelCodeResolver.DeleteField(component);
        }

        public void WriteScript()
        {
            panelCodeResolver.WriteScript();
        }
    }
}